package com.ihome.android.academy.db;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.BaseColumns;
import android.text.TextUtils;

import com.ihome.android.dl.core.DownloadTask;
import com.ihome.android.util.log.LogUtil;

/**
 * 保存全部升级信息，包括下载完成以及下载中的
 * 
 * @author Emerson
 * */
public final class UpdateApp implements BaseColumns {
	public static final String	TAG						= UpdateApp.class.getSimpleName();

	public static final String	TABLE_NAME				= "update_app";

	public static final String	DEFAULT_SORT_ORDER		= UpdateAppInfo.KEY_TIMESTAMP + " DESC";

	public static final String	CONTENT_ITEM_TYPE		= "vnd.android.cursor.item/" + TABLE_NAME;
	public static final String	CONTENT_TYPE			= "vnd.android.cursor.dir/" + TABLE_NAME;

	public static final Uri		CONTENT_URI				= Uri.parse("content://" + DBProvider.AUTHORITY + "/" + TABLE_NAME);

	public static final int		STATE_WAITING			= 0;																	// 处于等待状态
	public static final int		STATE_DOWNLOADING		= 1;																	// 正在下载状态
	public static final int		STATE_PAUSE				= 2;																	// 处于暂停
	public static final int		STATE_FINISH			= 3;																	// 已经下载完成，重复下载时出现的提示
	public static final int		STATE_CANCEL			= 4;																	// 取消下载
	public static final int		STATE_ERROR				= 5;																	// 下载错误（无法下载，断网等）
	public static final int		STATE_UPDATE_SUCCESS	= 6;																	// 升级成功

	public static void updateInsert(Context context, UpdateAppInfo value) {
		ContentResolver contentResolver = context.getContentResolver();
		Uri localUri = CONTENT_URI;
		ContentValues contentValues = value.UpdateAppInfo2ContentValues();
		if (value != null && !TextUtils.isEmpty(value.pkgName)) {
			Cursor cursor = contentResolver.query(localUri, null, UpdateAppInfo.KEY_PKGNAME + "=?", new String[] { value.pkgName }, null);
			if (cursor != null && cursor.getCount() > 0)
				contentResolver.update(localUri, contentValues, UpdateAppInfo.KEY_PKGNAME + "=?", new String[] { value.pkgName });
			else {
				contentResolver.insert(localUri, contentValues);
			}
			if (null != cursor)
				cursor.close();
		}
	}

	/**
	 * 获取数据库表{@value #TABLE_NAME}中 {@value #COLUMN_CONTENT_ID} 等于@param
	 * contentId
	 * 
	 * @return A UpdateAppInfo class;
	 * */
	public static UpdateAppInfo getUpdateAppByPkgName(Context context, String pkgName) {
		LogUtil.d(TAG, "getUpdateAppByPkgName pkgName = " + pkgName);
		UpdateAppInfo updateApp = null;
		if (pkgName != null) {
			ContentResolver c = context.getContentResolver();
			Cursor cursor = c.query(CONTENT_URI, null, UpdateAppInfo.KEY_PKGNAME + "=?", new String[] { pkgName }, DEFAULT_SORT_ORDER);

			if ((cursor != null) && (cursor.getCount() > 0)) {
				while (cursor.moveToNext()) {
					updateApp = new UpdateAppInfo();
					updateApp.status = cursor.getInt(cursor.getColumnIndex(UpdateAppInfo.KEY_STATUS));
					updateApp.timeStamp = cursor.getLong(cursor.getColumnIndex(UpdateAppInfo.KEY_TIMESTAMP));
					updateApp.pkgName = cursor.getString(cursor.getColumnIndex(UpdateAppInfo.KEY_PKGNAME));
					updateApp.filePath = cursor.getString(cursor.getColumnIndex(UpdateAppInfo.KEY_FILE_PATH));
					updateApp.version = cursor.getString(cursor.getColumnIndex(UpdateAppInfo.KEY_VERSION));
					updateApp.isUpdate = cursor.getInt(cursor.getColumnIndex(UpdateAppInfo.KEY_NEEDUPDATE)) == 0 ? false : true;
					LogUtil.v(TAG, "update  " + cursor.getString(cursor.getColumnIndex(UpdateAppInfo.KEY_NEEDUPDATE)));
					break;
				}
			}
			if (cursor != null)
				cursor.close();
		}
		if (null != updateApp)
			LogUtil.d(TAG, "getUpdateAppByPkgName " + updateApp.toString());
		return updateApp;
	}

	/**
	 * Deletes all rows from table {@value #TABLE_NAME} where column
	 * {@value #COLUMN_STATUS} equals parametric status's elements.
	 * 
	 * @return The number of rows deleted (If array status is null, return 0).
	 * 
	 * */
	public static int deleteAllData(Context context, String[] status) {
		LogUtil.d(TAG, "deleteAlldata");
		if (null != status && 0 < status.length) {
			String str = Arrays.toString(status);
			String where = UpdateAppInfo.KEY_STATUS + " IN ( " + str.substring(1, str.length() - 1) + ")";

			List<String> paths = getDeletePaths(context, where);
			int resultCode = context.getContentResolver().delete(CONTENT_URI, where, null);
			for (String path : paths) {
				File file = new File(path);
				if (file.exists()) {
					file.delete();
				}
			}
			return resultCode;
		}
		else
			return -1;
	}

	/**
	 * 获取内容的下载状态
	 * 
	 * @param context
	 * @param pkgName
	 *            App应用包名
	 * @return -1代表文件未下载 {@link DownloadTask}
	 */
	public static int getUpdateAppStatu(Context context, String pkgName) {
		Cursor cursor = context.getContentResolver().query(CONTENT_URI, new String[] { UpdateAppInfo.KEY_STATUS }, UpdateAppInfo.KEY_PKGNAME + " = " + pkgName, null, null);
		int statu = -1;
		if (null != cursor && cursor.getCount() > 0) {
			while (cursor.moveToNext()) {
				statu = cursor.getInt(0);
			}
			cursor.close();
		}
		return statu;
	}

	/**
	 * Deletes row(s) specified by a pkgName from table {@value #TABLE_NAME}.
	 * 
	 * @return The number of rows deleted.
	 * */
	public static int deleteByPkgName(Context context, String pkgName) {
		if (TextUtils.isEmpty(pkgName))
			return -1;
		// 规避当pkgName过长时，不加""查询不到的问题
		String idsStr = "";
		if (pkgName.contains(",")) {
			String[] ids = pkgName.split(",");
			for (int i = 0; i < ids.length; i++) {
				idsStr = (0 == i) ? ("\"" + ids[i] + "\"") : (idsStr = ", \"" + ids[i] + "\"");
			}
		}
		else
			idsStr = "\"" + pkgName + "\"";
		if (TextUtils.isEmpty(idsStr))
			return -1;
		LogUtil.d(TAG, "deleteContentId: " + pkgName);
		ContentResolver contentResolver = context.getContentResolver();
		String where = UpdateAppInfo.KEY_PKGNAME + " IN( " + idsStr + " )";
		List<String> paths = getDeletePaths(context, where);
		int resultCode = contentResolver.delete(CONTENT_URI, where, null);
		for (String path : paths) {
			File file = new File(path);
			if (file.exists()) {
				file.delete();
			}
		}
		return resultCode;
	}

	/**
	 * 删除下载的文件
	 * 
	 * @param context
	 * @param selection
	 */
	private static List<String> getDeletePaths(Context context, String selection) {
		List<String> paths = new ArrayList<String>();
		Cursor cursor = context.getContentResolver().query(CONTENT_URI, new String[] { UpdateAppInfo.KEY_FILE_PATH, UpdateAppInfo.KEY_STATUS }, selection, null, null);
		if (null != cursor && cursor.getCount() > 0) {
			while (cursor.moveToNext()) {
				String path = cursor.getString(0);
				path = (STATE_FINISH == cursor.getInt(1)) ? path : path + "temp";
				paths.add(path);
			}
		}
		cursor.close();
		return paths;
	}

	/**
	 * 获取下载记录中最新一条记录的下载状态
	 * 
	 * @param context
	 * @return
	 */
	public static int getTheLatestTaskStatu(Context context) {
		Cursor cursor = context.getContentResolver().query(CONTENT_URI, null, null, null, null);
		int resultStr = -1;
		if (null != cursor && 0 < cursor.getCount()) {
			if (cursor.moveToNext())
				resultStr = cursor.getInt(cursor.getColumnIndex(UpdateAppInfo.KEY_STATUS));
		}
		else {
			resultStr = -1;
		}
		LogUtil.e(TAG, "The latest task statu is : " + resultStr);
		cursor.close();
		return resultStr;
	}

	/**
	 * 获取数据库表{@value #TABLE_NAME}中全部数据
	 * 
	 * @return JSONArray.toString();
	 * */
	public static ArrayList<UpdateAppInfo> getAllUpdateApps(Context context) {
		LogUtil.d(TAG, "all UpdateApp");
		ContentResolver contentResolver = context.getContentResolver();
		Cursor cursor = contentResolver.query(CONTENT_URI, null, null, null, null);
		ArrayList<UpdateAppInfo> updateAppList = new ArrayList<UpdateAppInfo>();
		if ((cursor != null) && (cursor.getCount() > 0)) {
			while (cursor.moveToNext()) {
				UpdateAppInfo updateApp = new UpdateAppInfo();
				try {
					updateApp.status = cursor.getInt(cursor.getColumnIndex(UpdateAppInfo.KEY_STATUS));
					updateApp.timeStamp = cursor.getLong(cursor.getColumnIndex(UpdateAppInfo.KEY_TIMESTAMP));
					updateApp.filePath = cursor.getString(cursor.getColumnIndex(UpdateAppInfo.KEY_FILE_PATH));
					updateApp.pkgName = cursor.getString(cursor.getColumnIndex(UpdateAppInfo.KEY_PKGNAME));

					updateAppList.add(updateApp);

				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
		if (cursor != null)
			cursor.close();
		LogUtil.d(TAG, "all UpdateApp:  " + updateAppList.toString());
		return updateAppList;
	}

	/**
	 * 根据参数colums中的列名来获取数据库表{@value #TABLE_NAME}中{@value #COLUMN_STATUS}
	 * 列等于数组status中的值的信息; 目前仅用在初始化下载逻辑中的下载列表
	 * 
	 * @param context
	 * @param status
	 * 
	 * @return LinkedList<UpdateAppInfo>;
	 * */
	public static LinkedList<UpdateAppInfo> getUpdateAppsData(Context context, String[] status) {
		LogUtil.d(TAG, "getDownloadsData");
		for (String str : status)
			LogUtil.d(TAG, "status = " + str);

		ContentResolver contentResolver = context.getContentResolver();
		LogUtil.d(TAG, "contentResolver == null");
		Cursor cursor = null;
		if (null == status || 0 == status.length)
			cursor = contentResolver.query(CONTENT_URI, null, null, null, DEFAULT_SORT_ORDER);
		else {
			String str = Arrays.toString(status);
			String selection = UpdateAppInfo.KEY_STATUS + " IN ( " + str.substring(1, str.length() - 1) + ")";
			cursor = contentResolver.query(CONTENT_URI, null, selection, null, DEFAULT_SORT_ORDER);
		}

		LogUtil.d(TAG, "cursor == null");
		LinkedList<UpdateAppInfo> updateAppList = new LinkedList<UpdateAppInfo>();
		if ((cursor != null) && (cursor.getCount() > 0)) {
			while (cursor.moveToNext()) {
				UpdateAppInfo updateApp = new UpdateAppInfo();
				try {
					updateApp.status = cursor.getInt(cursor.getColumnIndex(UpdateAppInfo.KEY_STATUS));
					updateApp.timeStamp = cursor.getLong(cursor.getColumnIndex(UpdateAppInfo.KEY_TIMESTAMP));
					updateApp.filePath = cursor.getString(cursor.getColumnIndex(UpdateAppInfo.KEY_FILE_PATH));
					updateApp.pkgName = cursor.getString(cursor.getColumnIndex(UpdateAppInfo.KEY_PKGNAME));

					updateAppList.add(updateApp);

				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
		if (null != cursor)
			cursor.close();
		return updateAppList;
	}

	/**
	 * 根据参数colums中的列名来获取数据库表{@value #TABLE_NAME}中{@value #COLUMN_STATUS}
	 * 列等于数组status中的值 的 信息
	 * 
	 * @param context
	 * @param columns
	 *            表示需要获取的各个列名称,允许为NULL,此时获取全部列信息
	 * @param status
	 *            表示各种文件下载的状态，详细查看类DownloadControl中的下载状态,允许为NULL,此时获取全部状态信息
	 * 
	 * @return JSONArray.toString();
	 * */
	public static ArrayList<UpdateAppInfo> getUpdateAppsData(Context context, String[] columns, String[] status) {
		LogUtil.d(TAG, "getDownloadsData");
		if (null != columns) {
			for (String str : columns)
				LogUtil.d(TAG, "columns = " + str);
		}
		if (null != status) {
			for (String str : status)
				LogUtil.d(TAG, "status = " + str);
		}
		if (null != columns && 0 == columns.length)
			return null;
		ContentResolver contentResolver = context.getContentResolver();
		LogUtil.d(TAG, "contentResolver == null");
		Cursor cursor = null;
		if (null == status || 0 == status.length)
			cursor = contentResolver.query(CONTENT_URI, columns, null, null, DEFAULT_SORT_ORDER);
		else {
			String str = Arrays.toString(status);
			String selection = UpdateAppInfo.KEY_STATUS + " IN ( " + str.substring(1, str.length() - 1) + ")";
			cursor = contentResolver.query(CONTENT_URI, columns, selection, null, DEFAULT_SORT_ORDER);
		}

		// Cursor cursor = contentResolver.query(CONTENT_URI, null, null, null,
		// null);
		LogUtil.d(TAG, "cursor == null");

		ArrayList<UpdateAppInfo> updateAppList = new ArrayList<UpdateAppInfo>();
		if ((cursor != null) && (cursor.getCount() > 0)) {
			while (cursor.moveToNext()) {
				UpdateAppInfo updateApp = new UpdateAppInfo();
				try {
					updateApp.status = cursor.getInt(cursor.getColumnIndex(UpdateAppInfo.KEY_STATUS));
					updateApp.timeStamp = cursor.getLong(cursor.getColumnIndex(UpdateAppInfo.KEY_TIMESTAMP));
					updateApp.filePath = cursor.getString(cursor.getColumnIndex(UpdateAppInfo.KEY_FILE_PATH));
					updateApp.pkgName = cursor.getString(cursor.getColumnIndex(UpdateAppInfo.KEY_PKGNAME));

					updateAppList.add(updateApp);

				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
		if (null != cursor)
			cursor.close();
		LogUtil.d(TAG, "getDownloadsData " + updateAppList.toString());
		return updateAppList;
	}

	/**
	 * 判断是否存在{@value #COLUMN_CONTENT_ID} 等于 @param contentId 的数据
	 * 
	 * @param context
	 * @param contentId
	 * @return If exited data which {@value #COLUMN_CONTENT_ID} equals @param
	 *         contentId ,return true , or false;
	 * */
	public static boolean chkIsDownload(Context context, String pkgName) {
		LogUtil.d(TAG, "chkIsUpdate pkgName = " + pkgName);
		boolean b = false;
		if (pkgName != null) {
			ContentResolver c = context.getContentResolver();
			Cursor cursor = c.query(CONTENT_URI, null, UpdateAppInfo.KEY_PKGNAME + "=?", new String[] { pkgName }, null);
			b = (cursor != null) && (cursor.getCount() > 0);
			if (null != cursor)
				cursor.close();
		}
		return b;
	}

	/** Same with {@link #chkIsDownloads(Context, String)} */
	public static boolean isExist(Context context, String contentId) {
		return chkIsDownload(context, contentId);
	}

}